/**
 * Created by meiguizhinian on 2018/7/10
 * Copyright © 2018 lixiaolong. All rights reserved.
 */

//TODO：等待完成
//对象 let obj = new ll.Obj(param)
(function () {
	jssupport.RectCover = function () {
		//成员变量
		this.box = {x:0, y:0, width:0, height:0};
		this.unit = {width:0, height:0};
		this.children = new jssupport.RectArray();
	};
	let p = jssupport.RectCover.prototype;

	p.empty = function () {
		return Object.size(this.box)===0 && this.children.length === 0;
	};
	p.clear = function () {

	};

	// bool empty_grid(const Point<D, T>& point) const;
	p.empty_grid = function(grid) {
		let b1 = jssupport.rectContainsRect(this.box, grid);
		let b2 = !this.children.intersects(grid);
		return b1 && b2;
	};
	//
	// bool empty_grid_at_child_left(const std::tuple<OPT ...>& op) const;
	// bool empty_grid_at_child_right(const std::tuple<OPT ...>& op) const;
	// bool empty_grid_at_child_bottom(const std::tuple<OPT ...>& op) const;
	// bool empty_grid_at_child_top(const std::tuple<OPT ...>& op) const;
	//
	// bool empty_grid_at_child_left_or_right(const std::tuple<OPT ...>& op) const;
	// bool empty_grid_at_child_bottom_or_top(const std::tuple<OPT ...>& op) const;
	/**
	 *	@brief 在 side 方向上是否有空格
	 *	@param side 仅依据正负来分别取水平方向和竖直方向
	 */
	// bool empty_grid_at_child_side(const std::tuple<OPT ...>& op, const Point<D, int>& side) const;
	/**
	 *	@brief 在 side 方向上有多少个空格
	 *	@param side 仅依据正负来分别取水平方向和竖直方向
	 */
	// uint32_t empty_grid_count_at_child_side(const std::tuple<OPT ...>& op, const Point<D, int>& side) const;

	p.adjacent_to_child_right = function(name) {
		let child = this.children.find(name);
		if (!child) {
			return false;
		}
		return (child.x+child.width)>=this.box.width;
	};

	p.distance_at_child_right = function(name) {
		let child = this.children.find(name);
		if (!child) {
			return false;
		}
		return this.box.width-(child.x+child.width);
	};

	//void setChildOrigin(const std::tuple<OPT ...>& op, const Point<D, T>& origin);
	p.moveChildOrigin = function(name, vector) {
		let child = this.children.find(name);
		if (!child) {
			return;
		}
		child.x += vector.x;
		child.y += vector.y;
	};
	// void swapChildOrigin(const std::tuple<OPT ...>& op1, const std::tuple<OPT ...>& op2);
	////////////////////////////////////////////////////////////////////////////木块解救
	////////////////////////////////////////////////////////////////////////////对op标记的块是否可以移动判断及移动位置计算
	//OPT...: char 标记木块种类
	/**
	 * @brief 移动 child，child 在移动的过程中不和任何其他 child 发生相交
	 * @param name
	 * @param vector 移动的向量
	 * @param near 是否靠近网格
	 * @param pos 最后停留的位置
	 */
	p.moveChildLeftOrRight = function(name, vector, near, pos) {
		if (vector === 0) {
			return false;
		}
		let child = this.children.find(name);
		if (!child) {
			return false;
		}
		let point = child;
		if (vector>0) {
			let p0 = point.x + child.width;//这里会有误差
			let p1 = jssupport.NumberHelper.integer_multiple_ceil(p0, this.unit.width);
			if (p0 === p1) {
				p1 += this.unit.width;
			}
			if (!this.empty_grid(cc.rect(p0, point.y, p1-p0, this.unit.height))) {// 不能移动
				return false;
			}
			let dis = p1-p0;  // 可移动距离
			if (dis<vector) {  //单元格内可移动距离<希望移动距离
				// 计算最大可移动距离
				let np = cc.rect(p1, point.y, this.unit.width, this.unit.height);
				while (this.empty_grid(np)) {
					np.x += this.unit.width;
					dis += this.unit.width;
				}
				if (dis<vector) {//可移动距离不足，移动到边界
					pos.x = np.x-child.width;
				} else {//可以移动距离足够
					pos.x = point.x+vector;
					if (near) {
						pos.x = jssupport.NumberHelper.integer_multiple_ceil(pos, this.unit.width);
					}
				}
			} else {
				if (near) {
					pos.x = p1-child.width;
				} else {
					pos.x = point.x+vector;
				}
			}
		} else {
			let p0 = point.x;
			let p1 = jssupport.NumberHelper.integer_multiple_floor(p0, this.unit.width);
			if (p0 === p1) {
				p1 -= this.unit.width;
			}
			if (!this.empty_grid(cc.rect(p1, point.y, p0-p1, this.unit.height))) {
				return false;
			}
			let dis = p1-p0;//负的可移动距离
			if (dis>vector) {
				let np = cc.rect(p1-this.unit.width, point.y, this.unit.width, this.unit.height);
				while (this.empty_grid(np)) {
					np.x -= this.unit.width;
					dis -= this.unit.width;
				}
				if (dis>vector) {
					pos.x = np.x+this.unit.width;
				} else {
					pos.x = point.x+vector;
					if (near) {
						pos.x = jssupport.NumberHelper.integer_multiple_floor(pos, this.unit.width);
					}
				}
			} else {
				if (near) {
					pos.x = p1;
				} else {
					pos.x = point.x+vector;
				}
			}
		}
		point.x = pos.x;
		return true;
	};
	p.moveChildUpOrDown = function(name, vector, near, pos) {
		if (vector === 0) {
			return false;
		}
		let child = this.children.find(name);
		if (!child) {
			return false;
		}
		let point = child;
		if (vector>0) {
			let p0 = point.y + child.height;
			let p1 = jssupport.NumberHelper.integer_multiple_ceil(p0, this.unit.height);
			if (p0 === p1) {
				p1 += this.unit.height;
			}
			if (!this.empty_grid(cc.rect(point.x, p0, this.unit.width, p1-p0))) {// 不能移动
				return false;
			}
			let dis = p1-p0;//可移动距离
			if (dis<vector) {  // 移动受到限制
				//计算最大可移动距离
				let np = cc.rect(point.x, p1, this.unit.width, this.unit.height);
				while (this.empty_grid(np)) {
					np.y += this.unit.height;
					dis += this.unit.height;
				}
				if (dis<vector) {
					pos.y = np.y-child.height;
				} else {
					pos.y = point.y+vector;
					if (near) {
						pos.y = jssupport.NumberHelper.integer_multiple_ceil(pos.y, this.unit.width);
					}
				}
			} else {
				if (near) {
					pos.y = p1-child.height;
				} else {
					pos.y = point.y+vector;
				}
			}
		} else {
			let p0 = point.y;
			let p1 = jssupport.NumberHelper.integer_multiple_floor(p0, this.unit.height);//木块下边最近的单元格位置
			if (p0 === p1) {
				p1 -= this.unit.height;
			}
			if (!this.empty_grid(cc.rect(point.x, p1, this.unit.width, p0-p1))) {
				return false;
			}
			let dis = p1-p0;//负的可移动距离
			if (dis>vector) {
				let np = cc.rect(point.x, p1-this.unit.height, this.unit.width, this.unit.height);
				while (this.empty_grid(np)) {
					np.y -= this.unit.height;
					dis -= this.unit.height;
				}
				if (dis>vector) {//最大可移动距离<将要移动的距离,移动受到限制
					pos.y = np.y+this.unit.height;//移动到np.y上一次位置
				} else {//移动不受限制
					pos.y = point.y+vector;
					if (near) {
						pos.y = jssupport.NumberHelper.integer_multiple_floor(pos.y, this.unit.width);
					}
				}
			} else {
				if (near) {
					pos.y = p1;
				} else {//移动到
					pos.y = point.y+vector;
				}
			}
		}
		point.y = pos.y;
		return true;
	};

	// 移动向量的距离 小于 radius，位置吸附
	p.suckChildLeftOrRight = function(name, vector, radius, pos) {
		let child = this.children.find(name);
		if (!child) {
			return false;
		}
		let point = child;
		if (vector === 0) {
			return false;  //不需要移动
		} else if (vector>0) {
			if (vector>radius) {
				return false; //距离太大
			}
			pos.x = jssupport.NumberHelper.integer_multiple_floor(point.x+vector, this.unit.width);
		} else {
			if (vector<-radius) {
				return false; //距离太大
			}
			pos.x = jssupport.NumberHelper.integer_multiple_ceil(point.x+vector, this.unit.width);
		}
		if (pos.x === point.x) {//位置相同不需要移动
			return false;
		}
		point.x = pos.x;
		return true;
	};
	p.suckChildUpOrDown = function(name, vector, radius, pos) {
		let child = this.children.find(name);
		if (!child) {
			return false;
		}
		let point = child;
		if (vector === 0) {
			return false;  //不需要移动
		} else if (vector>0) {
			if (vector>radius) {
				return false; //距离太大
			}
			pos.y = jssupport.NumberHelper.integer_multiple_floor(point.y, this.unit.height);
		} else {
			if (-vector>radius) {
				return false; //距离太大
			}
			pos.y = jssupport.NumberHelper.integer_multiple_ceil(point.y, this.unit.height);
		}
		if (pos.y === point.y) {//位置相同不需要移动
			return false;
		}
		point.y = pos.y;
		return true;
	};

	//判断是否可以左右移动
	p.moveChildLeftOrRightEnable = function(name) {
		let child = this.children.find(name);
		if (!child) {
			return false;
		}
		{
			let p0 = child.x + child.width;
			let p1 = jssupport.NumberHelper.integer_multiple_ceil(p0, this.unit.width);
			if (p0 === p1) {
				p1 += this.unit.width;
			}
			if (this.empty_grid(cc.rect(p0, child.y, p1-p0, this.unit.height))) {
				return true;
			}
		}
		{
			let p0 = child.x;
			let p1 = jssupport.NumberHelper.integer_multiple_floor(p0, this.unit.width);
			if (p0 === p1) {
				p1 -= this.unit.width;
			}
			if (this.empty_grid(cc.rect(p1, child.y, p0-p1, this.unit.height))) {
				return true;
			}
		}
		return false;
	};

	p.moveChildUpOrDownEnable = function(name) {
		let child = this.children.find(name);
		if (!child) {
			return false;
		}
		{
			let p0 = child.y + child.height;
			let p1 = jssupport.NumberHelper.integer_multiple_ceil(p0, this.unit.height);
			if (p0 === p1) {
				p1 += this.unit.height;
			}
			if (this.empty_grid(cc.rect(child.x, p0, this.unit.width, p1-p0))) {
				return true;
			}
		}
		{
			let p0 = child.y;
			let p1 = jssupport.NumberHelper.integer_multiple_floor(p0, this.unit.height);
			if (p0 === p1) {
				p1 -= this.unit.height;
			}
			if (this.empty_grid(cc.rect(child.x, p1, this.unit.width, p0-p1))) {
				return true;
			}
		}
		return false;
	};

	//判断是否可以移动到边上
	p.moveChildToFarRightEnable = function(name) {
		let child = this.children.find(name);
		if (!child) {
			return false;
		}
		let rect = cc.rect(0,0,0,0);
		rect.x = child.x+child.width;
		rect.y = child.y;
		rect.width = this.box.width-rect.x;
		rect.height = child.height;
		return this.empty_grid(rect);
	};
	////////////////////////////////////////////////////////////////////////////消消乐
	//OPT...: char 标记动物种类，example:熊
	//			int 索引，example:0
	//是否能和左边或者右边的连成3个
	// bool tripleWithLeftOrRightEnable(const std::tuple<OPT ...>& op) const;
})();

